package cn.schoolwow.quickdao.module.database.ddl.action.service.column;

import cn.schoolwow.quickdao.annotation.IdStrategy;
import cn.schoolwow.quickdao.domain.database.parent.DatabaseType;
import cn.schoolwow.quickdao.domain.entity.common.TableColumn;
import cn.schoolwow.quickdao.domain.provider.DatabaseProvider;
import cn.schoolwow.quickdao.module.database.ddl.common.flow.v2.GetAutoIncrementStatementV2CommonFlow;
import cn.schoolwow.quickdao.module.database.ddl.query.service.entity.HasTableFlow;
import cn.schoolwow.quickdao.module.database.parent.flow.executor.ExecuteUpdateConnectionFlow;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;
import cn.schoolwow.util.domain.check.instance.CheckInstance;

public class CreateColumnServiceFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        checkRequest(flowContext);
        flowContext.executeFlowList(new HasTableFlow());
        setCreateColumnStatement(flowContext);
        executeStatement(flowContext);
    }

    @Override
    public String name() {
        return "根据TableColumn参数新增表字段";
    }

    private void checkRequest(FlowContext flowContext){
        TableColumn tableColumn = flowContext.checkInstanceData(TableColumn.class);

        CheckInstance.newCheck()
                .notEmptyCheck(tableColumn.column, "字段名称")
                .notEmptyCheck(tableColumn.columnType, "字段类型");
    }

    private void setCreateColumnStatement(FlowContext flowContext){
        String tableName = flowContext.checkData("tableName", String.class);
        TableColumn tableColumn = flowContext.checkInstanceData(TableColumn.class);
        DatabaseType databaseType = flowContext.checkInstanceData(DatabaseType.class);
        DatabaseProvider databaseProvider = flowContext.checkInstanceData(DatabaseProvider.class);

        switch (databaseType){
            case H2:{tableName = tableName.toUpperCase();}break;
        }

        StringBuilder sqlBuilder = new StringBuilder("alter table " + databaseProvider.escape(tableName) + " add ");
        flowContext.putTemporaryInstanceData(sqlBuilder, StringBuilder.class);

        if (tableColumn.id && tableColumn.strategy == IdStrategy.AutoIncrement) {
            flowContext.executeFlowList(new GetAutoIncrementStatementV2CommonFlow());
        } else {
            sqlBuilder.append(databaseProvider.escape(tableColumn.column) + " " + tableColumn.columnType + (null == tableColumn.range ? "" : "(" + tableColumn.range + ")"));
            if (null != tableColumn.defaultValue && !tableColumn.defaultValue.isEmpty()) {
                sqlBuilder.append(" default '" + tableColumn.defaultValue+"'");
            }
            if (null!=tableColumn.notNull&&tableColumn.notNull) {
                sqlBuilder.append(" not null");
            }
            if(flowContext.containKey("escapeCheck")){
                sqlBuilder.append(" check " + flowContext.checkData("escapeCheck"));
            }
            if (null != tableColumn.comment) {
                //sqlite不添加注释信息
                switch (databaseType){
                    case SQLite:{}break;
                    default:{
                        sqlBuilder.append(" " + databaseProvider.comment(tableColumn.comment));
                    }break;
                }
            }
        }
        sqlBuilder.append(";");
        //postgres数据库添加注释
        switch (databaseType){
            case Postgresql:{
                sqlBuilder.append("comment on column " + databaseProvider.escape(tableName) + "." + databaseProvider.escape(tableColumn.column) + " is '" + tableColumn.comment + "';");
            }break;
        }
        flowContext.putTemporaryData("sql", sqlBuilder.toString());
    }

    private void executeStatement(FlowContext flowContext){
        flowContext.startFlow(new ExecuteUpdateConnectionFlow())
                .putTemporaryData("name", "新增列")
                .execute();
    }
}
